#include <lib3d/hard/VertexBufferBuilder2D.h>

#include <SimpleArray.h>
#include <lib3d/hard/VertexBuffer.h>
#include <system/assert.h>

namespace liba {
namespace lib3d {
namespace hard {

void VertexBufferBuilder2D::AddRect(math::Rect<float> rect, math::Rect<int> texRect)
{
	float rectPositions[6 * 3];
	float rectUvs[6 * 2];

	float* pos_data = rectPositions;
	float* uvs_data = rectUvs;

	const float dx = rect.width;
	const float dy = rect.height;
	const float x = rect.x;
	const float y = rect.y;
	
	const float du = (float)texRect.width / (float)texWidth;
	const float dv = -(float)texRect.height / (float)texHeight;
	const float u = (float)texRect.x  / (float)texWidth;
	const float v = (float)(texRect.y + texRect.height) / (float)texHeight;

	*pos_data++ = x;
	*pos_data++ = y;
	*pos_data++ = z;
	*uvs_data++ = u;
	*uvs_data++ = v;

	*pos_data++ = x;
	*pos_data++ = y + dy;
	*pos_data++ = z;
	*uvs_data++ = u;
	*uvs_data++ = v + dv;

	*pos_data++ = x + dx;
	*pos_data++ = y;
	*pos_data++ = z;
	*uvs_data++ = u + du;
	*uvs_data++ = v;

	*pos_data++ = x + dx;
	*pos_data++ = y;
	*pos_data++ = z;
	*uvs_data++ = u + du;
	*uvs_data++ = v;

	*pos_data++ = x;
	*pos_data++ = y + dy;
	*pos_data++ = z;
	*uvs_data++ = u;
	*uvs_data++ = v + dv;

	*pos_data++ = x + dx;
	*pos_data++ = y + dy;
	*pos_data++ = z;
	*uvs_data++ = u + du;
	*uvs_data++ = v + dv;

	this->positions.insert(this->positions.end(), rectPositions, rectPositions + 6 * 3);
	this->uvs.insert(this->uvs.end(), rectUvs, rectUvs + 6 * 2);
}

void VertexBufferBuilder2D::UpdateVertexBuffer(VertexBuffer* vb)
{
	SimpleArray<float> localPositions(this->positions.size());
	if (!this->positions.empty())
		memcpy(localPositions.data(), &this->positions[0], sizeof(float) * this->positions.size());
	SimpleArray<float> localUvs(this->uvs.size());
	if (!this->uvs.empty())
		memcpy(localUvs.data(), &this->uvs[0], sizeof(float) * this->uvs.size());

	SimpleArray<float> emptyFloat;
	vb->update(localPositions, emptyFloat, emptyFloat, localUvs, localUvs);
}


} // namespace hard
} // namespace lib3d
} // namespace liba